<template>
  <div class="hmi-table-cell">
    <!-- 枚举类型 -->
    <el-select
      v-if="column.type === 'enum'"
      :model-value="modelValue"
      :disabled="!editable"
      @update:model-value="handleValueUpdate"
      class="w-full"
      size="small"
    >
      <el-option
        v-for="option in column.enumOptions"
        :key="option.Value"
        :label="option.Desc"
        :value="option.Value"
      />
    </el-select>

    <!-- 数字类型 -->
    <el-input-number
      v-else-if="column.type === 'number'"
      :model-value="modelValue"
      :disabled="!editable"
      :min="column.min"
      :max="column.max"
      :step="column.step || 1"
      :precision="column.fix || getPrecision(column.step)"
      @update:model-value="handleValueUpdate"
      class="w-full"
      size="small"
    />

    <!-- 字符串类型 -->
    <el-input
      v-else-if="column.type === 'string'"
      :model-value="modelValue"
      :disabled="!editable"
      :maxlength="column.maxLength"
      @update:model-value="handleValueUpdate"
      class="w-full"
      size="small"
    />

    <!-- 布尔类型 -->
    <el-switch
      v-else-if="column.type === 'boolean'"
      :model-value="modelValue"
      size="small"
      :disabled="!editable"
      @update:model-value="handleValueUpdate"
    />

    <!-- 默认显示 -->
    <span v-else class="text-gray-500">
      {{ formatDisplayValue(modelValue) }}
    </span>

    <!-- 验证错误提示 -->
    <div v-if="validationError" class="text-red-500 text-xs mt-1">
      {{ validationError }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import type { HmiColumnConfig } from "../types";

interface Props {
  modelValue: any;
  column: HmiColumnConfig;
  editable?: boolean;
}

interface Emits {
  (e: "update:modelValue", value: any): void;
  (e: "change", value: any): void;
}

const props = withDefaults(defineProps<Props>(), {
  editable: true,
});

const emit = defineEmits<Emits>();

const validationError = ref<string>("");

// 计算精度
function getPrecision(step?: number): number {
  if (!step) return 0;
  const stepStr = step.toString();
  const decimalIndex = stepStr.indexOf(".");
  return decimalIndex === -1 ? 0 : stepStr.length - decimalIndex - 1;
}

// 格式化显示值
function formatDisplayValue(value: any): string {
  if (value === null || value === undefined) return "";
  if (typeof value === "boolean") return value ? "是" : "否";
  if (typeof value === "object") return JSON.stringify(value);
  return String(value);
}

// 验证值
function validateValue(value: any): string {
  if (props.column.required && (value === null || value === undefined || value === "")) {
    return "此字段为必填项";
  }

  if (props.column.type === "number") {
    const num = Number(value);
    if (isNaN(num)) return "请输入有效数字";
    if (props.column.min !== undefined && num < props.column.min) {
      return `值不能小于 ${props.column.min}`;
    }
    if (props.column.max !== undefined && num > props.column.max) {
      return `值不能大于 ${props.column.max}`;
    }
  }

  if (props.column.type === "string") {
    const str = String(value);
    if (props.column.maxLength && str.length > props.column.maxLength) {
      return `长度不能超过 ${props.column.maxLength} 个字符`;
    }
    if (props.column.pattern && !props.column.pattern.test(str)) {
      return "格式不正确";
    }
  }

  return "";
}

// 处理值更新
function handleValueUpdate(value: any) {
  const error = validateValue(value);
  validationError.value = error;

  if (!error) {
    emit("update:modelValue", value);
    emit("change", value);
  }
}

// 监听值变化进行验证
watch(
  () => props.modelValue,
  (newValue) => {
    if (props.editable) {
      validationError.value = validateValue(newValue);
    }
  },
  { immediate: true }
);
</script>

<style scoped>
.hmi-table-cell {
  width: 100%;
}

.w-full {
  width: 100%;
}

.text-gray-500 {
  color: #6b7280;
}

.text-red-500 {
  color: #ef4444;
}

.text-xs {
  font-size: 0.75rem;
}

.mt-1 {
  margin-top: 0.25rem;
}
</style>
